package hershey.java07001.java_basic.a_demo.m001.non_access_modifiers;

import java.util.ArrayList;
import java.util.List;

/**
 * 作用：确保不可更改性，即一旦使用了 final 修饰符，修饰的元素就不能被修改
 * 1. final修饰变量
 * 2. final修饰方法
 * 3. final修饰类
 * 4. final修饰引用变量
 */
public class M001_Final {

    //成员变量：对于类的成员变量，可以在声明时赋值，或者在构造方法中进行赋值。一旦赋值后，该成员变量的值就不能再被改变
    private final String final_variables_string = "final_variables_string";

    //静态变量：final 修饰的静态变量通常被称为“常量”，必须在声明时或在静态代码块中初始化。常量的命名通常是大写字母。
    public static final int MAX_VALUE = 100;

    public void a_method() {

        //局部变量被 final 修饰后，必须在声明时或构造函数中进行赋值，而且赋值后不能再改变
        final String final_variables_a = "final_variables_a";
        //final_variables_a = "final_variables_b"; //这会导致编译错误，因为 x 已经是一个 final 变量

        //final 修饰参考变量
        //当一个对象引用被声明为 final 时，该引用不能被更改为指向另一个对象。但是，引用对象的内部状态是可以改变的。
        // 这意味着 final 确保引用本身是不可变的，而不是引用指向的对象是不可变的。
        final List<String> list = new ArrayList<>();
        list.add("Hello");
        // list = new ArrayList<>(); // 这会导致编译错误，因为 list 是 final
    }

    /**
     * 当一个方法被 final修饰时，这个方法不能被子类重写。这在设计不可改变的方法时非常有用，尤其是在一些关键的类中，
     * 通过final来防止方法的逻辑被子类意外或恶意更改。
     */
    public final void display() {
        System.out.println("This is a final method.");
    }

    public class Child_M001_Final extends M001_Final {
        // 试图重写 display 方法会导致编译错误
        // public void display() { // 这会导致编译错误 }
    }

    public final class Final_M001_Final {
        public static void performTask() {
            System.out.println("Task performed.");
        }
    }

    // 试图继承 Final_M001_Final 类会导致编译错误
    // public class Sub_Final_M001_Final extends Final_M001_Final { // 这会导致编译错误 }
}
